package com.dagit.core.map.proxy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.dagit.network.Instance;
import com.dagit.network.traffic.Clear;
import com.dagit.network.traffic.ContainsKey;
import com.dagit.network.traffic.ContainsValue;
import com.dagit.network.traffic.Get;
import com.dagit.network.traffic.GetSize;
import com.dagit.network.traffic.IsEmpty;
import com.dagit.network.traffic.Message;
import com.dagit.network.traffic.NetworkEngine;
import com.dagit.network.traffic.Values;

/**
 * @author ibrahimb
 * Bu sinif sadece istenilen ozelligi tum serverlardan ceker ve tum data yerine size isteniyorsa bir int degeri alir. 
 * ihtiyac olunmayan hic bir zaman icinde data bulunmaz
 * @param <K>
 * @param <V>
 */
public class DirectProxyMap<K,V>  implements ProxyMap<K, V>{
	private Object key;
	public DirectProxyMap(Object key){
		this.key = key;
	}
	
	
	private Message<Object> getQueryMessage(Class<?> clazz){
		Message<Object> message = new Message<Object>();
		message.setClazz(clazz.getName());
		message.setInput(key);
		return message;
	}
	
	@Override
	public int size() {
		List<Integer> sizes = NetworkEngine.collectResponses(getQueryMessage(GetSize.class));
		int size = 0;
		for(Integer val : sizes){
			size += val.intValue();
		}
		return size;
	}

	@Override
	public boolean isEmpty() {
		List<Instance> instances = NetworkEngine.getInstances();
		Message<Object> message = getQueryMessage(IsEmpty.class);
		for (Instance instance : instances){
			Boolean empty = NetworkEngine.query(instance, message);
			if (empty.booleanValue() == false){
				return false;
			}
		}
		return true;
	}

	@Override
	public boolean containsKey(Object key) {
		List<Instance> instances = NetworkEngine.getInstances();
		Message<Object[]> message = new Message<Object[]>();
		message.setClazz(ContainsKey.class.getName());
		message.setInput(new Object[]{this.key,key});
		for(Instance instance : instances){
			Boolean containsKey = NetworkEngine.query(instance, message);
			if (containsKey == true){
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean containsValue(Object value) {
		List<Instance> instances =  NetworkEngine.getInstances();
		Message<Object[]> message = new Message<Object[]>();
		message.setClazz(ContainsValue.class.getName());
		message.setInput(new Object[]{key,value});
		for(Instance instance : instances){
			Boolean containsValue = NetworkEngine.query(instance, message);
			if (containsValue == true){
				return true;
			}
		}
		return false;
	}

	@Override
	public V get(Object key) {
		List<Instance> instances =  NetworkEngine.getInstances();
		Message<Object[]> message = new Message<Object[]>();
		message.setClazz(Get.class.getName());
		message.setInput(new Object[]{this.key,key});
		for(Instance instance : instances){
			V value = NetworkEngine.query(instance, message);
			if (value != null){
				return value;
			}
		}
		return null;
	}

	@Override
	public V put(K key, V value) {
		// TODO this method requires
		return null;
	}

	@Override
	public V remove(Object key) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void putAll(Map<? extends K, ? extends V> m) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void clear() {
		NetworkEngine.collectResponses(getQueryMessage(Clear.class));
	}

	@Override
	public Set<K> keySet() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Collection<V> values() {
		List<Collection<V>> others = NetworkEngine.collectResponses(getQueryMessage(Values.class));
		Collection<V> values = new ArrayList<V>();
		for(Collection<V> value : others){
			values.addAll(value);
		}
		return values;
	}

	@Override
	public Set<java.util.Map.Entry<K, V>> entrySet() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<K, V> getLocalMap() {
		return null;
	}

}
